import typing, json

from fastapi.encoders import jsonable_encoder

from app.corelibs.codes import CodeEnum
from app.models.hrms_models import Department, Duty
from app.schemas.hrms.hrms_schemas import DepartmentSchemas, DutySchemas


class DepartmentService:

    @staticmethod
    async def department_list(params: DepartmentSchemas) -> typing.List[typing.Any]:
        """查询组织列表分页"""
        return await Department.get_department_list(params)

    @staticmethod
    async def all_department_list() -> typing.List[typing.Any]:
        """不分页"""
        return await Department.get_department_all()

    @staticmethod
    def department_assembly(parent_department: typing.List[typing.Any], all_department: typing.List[typing.Any]) -> \
            typing.List[typing.Any]:
        """
        递归遍历组织
        :param parent_department: 一级组织列表
        :param all_department: 所有组织
        :return:
        """
        for parent in parent_department:
            # DepartmentService.assemble_menu_data(parent)
            for department in all_department:
                if department['parent_id'] == parent['id']:
                    parent['children'] = [] if not parent.get('children', None) else parent['children']
                    # MenuService.assemble_menu_data(menu)
                    parent['children'].append(department)
            DepartmentService.department_assembly(parent['children'], all_department) if parent.get('children',
                                                                                                    None) else ...
        return parent_department

    @staticmethod
    async def department_tree() -> typing.List[typing.Any]:
        """嵌套组织树"""
        all_department = jsonable_encoder(await DepartmentService.all_department_list())
        if all_department:
            parent_department = [department for department in all_department if department["parent_id"] == 0]
            result = DepartmentService.department_assembly(parent_department, all_department)
            return result

    @staticmethod
    async def list(params: DepartmentSchemas) -> typing.Dict:
        """
        获取列表
        :param params:
        :return:
        """
        data = await Department.get_list(params)
        return data

    # @staticmethod
    # async def handle_router(dep: DepartmentSchemas, parent_info: dict):
    #     """
    #     截取末级获取父级路由
    #     """
    #     dep.department_route_id = ",".join([parent_info['department_route_id'], dep.id])
    #     dep.department_route = ",".join([parent_info['department_route_id'], dep.name])

    @staticmethod
    async def save_or_update(params: DepartmentSchemas) -> typing.Dict:
        """
        更新组织信息
        :param params:
        :return:
        """
        if await Department.get_department_by_name(params.name):
            if not params.id:
                raise ValueError('组织名称已存在！')

        # ext_data = await Department.get(params.id)
        # 更新组织数据
        ext_data = await Department.create_or_update(params.dict())

        # 更新数据，计算父级路由id和name
        if ext_data:
            parent_info = await Department.get_department_by_parent_id(params.parent_id)
            if parent_info:
                ext_data = DepartmentSchemas(**ext_data)
                ext_data.department_route_id = "/".join([parent_info['department_route_id'], str(ext_data.id)])
                ext_data.department_route = "/".join([parent_info['department_route'], ext_data.name])
                ext_data.parent_name = parent_info['name']
                ext_data = ext_data.dict()
                # await DepartmentService.handle_router(params, parent_info)
            else:
                ext_data['department_route_id'] = str(ext_data['id'])
                ext_data['department_route'] = ext_data['name']
        else:
            # 没有id重新赋值路由
            ext_data['department_route_id'] = str(ext_data['id'])
            ext_data['department_route'] = ext_data['name']

        # 更新组织信息
        ext_data = await Department.create_or_update(ext_data)

        # 获取修改前的组织路径
        old_department_route_id = ext_data['department_route_id'] if ext_data else None
        old_department_route = ext_data['department_route'] if ext_data else None

        # 处理子级
        c_dep_infos = await Department.get_department_route_id(params.department_route_id)
        if c_dep_infos:
            for dep in c_dep_infos:
                if old_department_route_id:
                    dep["department_route_id"] = dep["department_route_id"].replace(params.department_route_id,
                                                                                    str(ext_data['department_route_id']))
                if old_department_route:
                    dep["department_route"] = dep["department_route"].replace(params.department_route,
                                                                              ext_data['department_route'])
                await Department.create_or_update(dep)

    @staticmethod
    async def deleted(params: DepartmentSchemas) -> int:
        """
        删除组织
        :param params:
        :return:
        """
        data = await Department.get_department_by_id(params)
        if data:
            return await Department.delete(params.id)


class DutyService:
    @staticmethod
    async def list(params: DutySchemas) -> typing.Dict:
        """
        获取列表
        :param params:
        :return:
        """
        data = await Duty.get_list(params)
        return data

    @staticmethod
    async def save_or_update(params: DutySchemas) -> typing.Dict:
        """
        更新组织信息
        :param params:
        :return:
        """

        return await Duty.create_or_update(params.dict())

    @staticmethod
    async def deleted(params: DutySchemas) -> int:
        """
        删除组织
        :param params:
        :return:
        """
        data = await Duty.get_duty_by_id(params)
        if data:
            return await Duty.delete(params.id)
